package cn.iocoder.yudao.module.member.service.praxisProject;

import cn.iocoder.yudao.framework.common.exception.ErrorCode;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.pojo.SortingField;
import cn.iocoder.yudao.framework.common.util.date.DateUtils;
import cn.iocoder.yudao.framework.common.util.number.NumberUtils;
import cn.iocoder.yudao.framework.mybatis.core.util.MyBatisUtils;
import cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils;
import cn.iocoder.yudao.framework.tenant.core.aop.TenantIgnore;
import cn.iocoder.yudao.framework.web.core.util.WebFrameworkUtils;
import cn.iocoder.yudao.module.member.controller.admin.praxisProject.vo.*;
import cn.iocoder.yudao.module.member.dal.dataobject.praxisAnnex.PraxisAnnexDO;
import cn.iocoder.yudao.module.member.dal.dataobject.praxisEntryInfo.PraxisEntryInfoDO;
import cn.iocoder.yudao.module.member.dal.dataobject.praxisProject.PraxisProjectDO;
import cn.iocoder.yudao.module.member.dal.dataobject.praxisProjectSchedule.PraxisProjectScheduleDO;
import cn.iocoder.yudao.module.member.dal.mysql.praxisEntryInfo.PraxisEntryInfoMapper;
import cn.iocoder.yudao.module.member.dal.mysql.praxisProject.PraxisProjectMapper;
import cn.iocoder.yudao.module.member.dal.mysql.praxisProjectResult.PraxisProjectResultMapper;
import cn.iocoder.yudao.module.member.service.praxisAnnex.PraxisAnnexService;
import cn.iocoder.yudao.module.member.service.praxisProjectSchedule.PraxisProjectScheduleService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import javax.annotation.Resource;
import java.util.*;

import static cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil.exception;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.PRAXIS_PROJECT_NOT_DOUBLE;
import static cn.iocoder.yudao.module.member.enums.ErrorCodeConstants.PRAXIS_PROJECT_NOT_EXISTS;

/**
 * 实践项目 Service 实现类
 *
 * @author 管理员
 */
@Service
@Validated
public class PraxisProjectServiceImpl implements PraxisProjectService {

    @Resource
    private PraxisProjectMapper praxisProjectMapper;
    @Resource
    private PraxisAnnexService praxisAnnexService;
    @Resource
    private PraxisProjectScheduleService praxisProjectScheduleService;
    @Resource
    private PraxisEntryInfoMapper praxisEntryInfoMapper;
    @Resource
    private PraxisProjectResultMapper praxisProjectResultMapper;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long createPraxisProject(PraxisProjectCreateReqVO projectVO) {
        // 插入
        PraxisProjectDO praxisProjectDO=new PraxisProjectDO();
        BeanUtils.copyProperties(projectVO,praxisProjectDO);
        String username = SecurityFrameworkUtils.getLoginUser().getUsername();
        praxisProjectDO.setCreator(username);
        praxisProjectDO.setUpdater(username);
        praxisProjectDO.setUserId(SecurityFrameworkUtils.getLoginUser().getId());
        Date date = new Date();
        Integer maxWeight = NumberUtils.getInteger(praxisProjectMapper.getMaxWeight(null)) ;
        praxisProjectDO.setWeight(maxWeight+1);
        praxisProjectMapper.insert(praxisProjectDO);
        List<PraxisAnnexVO> annexVOList = projectVO.getAnnexVOList();
        if(CollectionUtils.isNotEmpty(annexVOList)){
            List<PraxisAnnexDO> annexDTOList=new ArrayList<>();
            annexVOList.stream().forEach(m->{
                PraxisAnnexDO p=new PraxisAnnexDO();
                BeanUtils.copyProperties(m,p);
                p.setId(null);
                p.setRelationId(praxisProjectDO.getId());
                p.setRelationType(1);
                p.setCreator(username);
                p.setCreateTime(date);
                annexDTOList.add(p);
            });
            praxisAnnexService.batchSavePraxisAnnex(annexDTOList);
        }
        List<PraxisProjectScheduleVO> scheduleVOList = projectVO.getScheduleVOList();
        if(CollectionUtils.isNotEmpty(scheduleVOList)){
            List<PraxisProjectScheduleDO> scheduleDTOList=new ArrayList<>();
            scheduleVOList.stream().forEach(m->{
                PraxisProjectScheduleDO p=new PraxisProjectScheduleDO();
                BeanUtils.copyProperties(m,p);
                p.setId(null);
                p.setCreator(username);
                p.setProjectId(praxisProjectDO.getId());
                p.setCreateTime(date);
                scheduleDTOList.add(p);
            });
            praxisProjectScheduleService.batchSaveProjectSchedule(scheduleDTOList);
        }
        this.saveProjectRecord(praxisProjectDO.getId(),1);
        return praxisProjectDO.getId();
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updatePraxisProject(PraxisProjectUpdateReqVO projectVO) {
        // 校验存在
        this.validatePraxisProjectExists(projectVO.getId());
        PraxisProjectDO praxisProjectDO=new PraxisProjectDO();
        BeanUtils.copyProperties(projectVO,praxisProjectDO);
        String username = SecurityFrameworkUtils.getLoginUser().getUsername();
        praxisProjectDO.setUpdater(username);
        Date date = new Date();
        List<PraxisProjectScheduleVO> scheduleVOList = projectVO.getScheduleVOList();
        if("1".equals(praxisProjectDO.getStatus())){
            PraxisProjectScheduleVO pr = scheduleVOList.stream().filter(m -> (m.getStartTime().before(new Date()) && m.getEndTime().after(new Date())))
                    .findFirst().orElse(null);
            if(null!=pr && null!=pr.getScheduleType()){
                praxisProjectDO.setScheduleType(pr.getScheduleType());
            }
            praxisProjectDO.setReleaseTime(date);
        }
        praxisProjectMapper.updateById(praxisProjectDO);
        List<PraxisAnnexVO> annexVOList = projectVO.getAnnexVOList();
        praxisAnnexService.deletePraxisAnnexByProjectId(praxisProjectDO.getId(),1);
        if(CollectionUtils.isNotEmpty(annexVOList)){
            List<PraxisAnnexDO> annexDTOList=new ArrayList<>();
            annexVOList.stream().forEach(m->{
                PraxisAnnexDO p=new PraxisAnnexDO();
                BeanUtils.copyProperties(m,p);
                p.setId(null);
                p.setRelationId(praxisProjectDO.getId());
                p.setRelationType(1);
                p.setCreateTime(date);
                p.setCreator(username);
                annexDTOList.add(p);
            });
            praxisAnnexService.batchSavePraxisAnnex(annexDTOList);
        }
        praxisProjectScheduleService.deleteProjectScheduleByProjectId(praxisProjectDO.getId());
        if(CollectionUtils.isNotEmpty(scheduleVOList)){
            List<PraxisProjectScheduleDO> scheduleDTOList=new ArrayList<>();
            scheduleVOList.stream().forEach(m->{
                PraxisProjectScheduleDO p=new PraxisProjectScheduleDO();
                BeanUtils.copyProperties(m,p);
                p.setId(null);
                p.setCreator(username);
                p.setCreateTime(date);
                p.setProjectId(praxisProjectDO.getId());
                scheduleDTOList.add(p);
            });
            praxisProjectScheduleService.batchSaveProjectSchedule(scheduleDTOList);
        }
        this.saveProjectRecord(praxisProjectDO.getId(),2);
    }

    @Override
    public void submitPraxisProject(Long id) {
        PraxisProjectDO praxisProjectDO=new PraxisProjectDO();
        String username = SecurityFrameworkUtils.getLoginUser().getUsername();
        praxisProjectDO.setId(id);
        praxisProjectDO.setStatus(1);
        praxisProjectDO.setExamineStatus("1");
        praxisProjectDO.setExamineFlag("2");
        praxisProjectDO.setExaminePeople(username);
        Date date = new Date();
        praxisProjectDO.setExamineTime(date);
        praxisProjectDO.setSubmitTime(date);
        praxisProjectDO.setReleaseTime(date);
        praxisProjectDO.setUpdateTime(date);
        praxisProjectDO.setUpdater(username);
        if("1".equals(praxisProjectDO.getExamineStatus())){
            Integer scheduleType = praxisProjectMapper.getScheduleType(praxisProjectDO.getId());
            if(null!=scheduleType){
                praxisProjectDO.setScheduleType(scheduleType);
            }
        }
        praxisProjectMapper.updateById(praxisProjectDO);
        this.saveProjectRecord(id,9);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void underPraxisProject(Long id) {
        PraxisProjectDO praxisProjectDO=new PraxisProjectDO();
        String username = SecurityFrameworkUtils.getLoginUser().getUsername();
        praxisProjectDO.setUpdateTime(new Date());
        praxisProjectDO.setUpdater(username);
        praxisProjectDO.setStatus(2);
        praxisProjectDO.setId(id);
        praxisProjectMapper.updateById(praxisProjectDO);
        //删除关联数据(报名，公示)
        praxisEntryInfoMapper.deleteEntryStudentByProjectId(id);
        praxisEntryInfoMapper.deleteFeedBackByProjectId(id);
        praxisEntryInfoMapper.delete(new QueryWrapper<PraxisEntryInfoDO>().eq("project_id",id));
        praxisProjectResultMapper.deleteProjectResultByProjectId(id);
        this.saveProjectRecord(id,8);

    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void examinePraxisProject(PraxisProjectExamineReqVO updateReqVO) {
        // 校验存在
        this.validatePraxisProjectExists(updateReqVO.getId());
        PraxisProjectDO projectDO=new PraxisProjectDO();
        BeanUtils.copyProperties(updateReqVO,projectDO);
        Date date = new Date();
        projectDO.setExaminePeople(WebFrameworkUtils.getLoginUserName());
        projectDO.setExamineFlag("2");
        projectDO.setUpdater(WebFrameworkUtils.getLoginUserName());
        projectDO.setUpdateTime(date);
        if("1".equals(projectDO.getExamineStatus())){
            projectDO.setStatus(1);
            projectDO.setReleaseTime(new Date());
            Integer scheduleType = praxisProjectMapper.getScheduleType(projectDO.getId());
            if(null!=scheduleType){
                projectDO.setScheduleType(scheduleType);
            }
            this.saveProjectRecord(updateReqVO.getId(),5);
        }else{
            projectDO.setStatus(0);
            this.saveProjectRecord(updateReqVO.getId(),4);
        }
        praxisProjectMapper.updateById(projectDO);
    }

    @Override
    @TenantIgnore
    @Transactional(rollbackFor = Exception.class)
    public void deletePraxisProject(Long id) {
        // 校验存在
        this.validatePraxisProjectExists(id);
        //删除关联数据(报名，公示)
        praxisEntryInfoMapper.deleteEntryStudentByProjectId(id);
        praxisEntryInfoMapper.deleteFeedBackByProjectId(id);
        praxisEntryInfoMapper.delete(new QueryWrapper<PraxisEntryInfoDO>().eq("project_id",id));
        praxisProjectResultMapper.deleteProjectResultByProjectId(id);
        // 删除
        this.saveProjectRecord(id,6);
        praxisProjectMapper.deleteById(id);
    }

    @Override
    @TenantIgnore
    public void updateShowFlag(Long id) {
        // 校验存在
        PraxisProjectDO projectDO = this.validatePraxisProjectExists(id);
        Integer showFlag=NumberUtils.getInteger(projectDO.getShowFlag(),0);
        if(0==showFlag){
            showFlag=1;
        }else{
            showFlag=0;
        }
        praxisProjectMapper.update(Wrappers.<PraxisProjectDO>lambdaUpdate().set(PraxisProjectDO::getShowFlag,showFlag)
                .eq(PraxisProjectDO::getId,id));
    }


    public void saveProjectRecord(Long id,Integer recordType){
        PraxisProjectRecordVO recordDO=new PraxisProjectRecordVO();
        recordDO.setCreator(WebFrameworkUtils.getLoginUserName());
        Date date = new Date();
        recordDO.setCreateTime(date);
        recordDO.setProjectId(id);
        recordDO.setUserId(WebFrameworkUtils.getLoginUserId());
        recordDO.setRecordTime(date);
        recordDO.setRecordType(recordType);
        praxisProjectMapper.saveProjectRecord(recordDO);
    }

    private PraxisProjectDO validatePraxisProjectExists(Long id) {
        PraxisProjectDO projectDO = praxisProjectMapper.selectById(id);
        if (projectDO== null) {
            throw exception(PRAXIS_PROJECT_NOT_EXISTS);
        }
        return projectDO;
    }

    @Override
    public PraxisProjectDO getPraxisProject(Long id) {
        return praxisProjectMapper.selectById(id);
    }

    @Override
    public PraxisProjectRespVO getProjectInfoById(Long id) {
        return praxisProjectMapper.getProjectInfoById(id);
    }

    @Override
    public List<PraxisProjectRespVO> getPraxisProjectList(String title, Integer queryType) {
        List<PraxisProjectRespVO> list = praxisProjectMapper.getPraxisProjectListByTitle(title,queryType);
        return list;
    }

    @Override
    @TenantIgnore
    public PraxisProjectRespVO getPraxisProjectInfoById(Long id,Integer scheduleType) {
        return praxisProjectMapper.getPraxisProjectInfoById(id,scheduleType);
    }
    @Override
    public void top(Long id,Long projectTypeId) {
        Integer maxWeight = NumberUtils.getInteger(praxisProjectMapper.getMaxWeight(null)) ;
        PraxisProjectDO p=new PraxisProjectDO();
        p.setId(id);
        p.setWeight(maxWeight+1);
        praxisProjectMapper.updateById(p);
    }

    @Override
    public void saveProjectScheduleVO(PraxisProjectScheduleVO projectVO) {
        this.validatePraxisProjectExists(projectVO.getId());
        List<PraxisProjectScheduleVO> scheduleVOList = praxisProjectScheduleService.getScheduleListByProjectId(projectVO.getProjectId());
        PraxisProjectScheduleVO v= scheduleVOList.stream().filter(m->m.getScheduleType().equals(projectVO.getScheduleType())).findFirst().orElse(null);
        if(null==v){
            throw exception(PRAXIS_PROJECT_NOT_DOUBLE);
        }
        scheduleVOList.add(projectVO);
        String msg = validateScheduleTime(scheduleVOList,2);

        if(StringUtils.isNotBlank(msg)){
            ErrorCode PRAXIS_PROJECT_NOT_DOUBLE= new ErrorCode(1004001036, msg);
            throw exception(PRAXIS_PROJECT_NOT_DOUBLE);
        }
        msg = validateUpdateSchedule(scheduleVOList,projectVO.getId());
        if(StringUtils.isNotBlank(msg)){
            ErrorCode PRAXIS_PROJECT_NOT_DOUBLE= new ErrorCode(1004001037, msg);
            throw exception(PRAXIS_PROJECT_NOT_DOUBLE);
        }
        PraxisProjectScheduleDO d=new PraxisProjectScheduleDO();
        BeanUtils.copyProperties(projectVO,d);
        praxisProjectScheduleService.save(d);
    }

    @Override
    @TenantIgnore
    public PageResult<PraxisProjectRespVO> getPraxisProjectPage(PraxisProjectPageReqVO pageReqVO) {
        // MyBatis Plus 查询
        IPage<PraxisProjectRespVO> mpPage = MyBatisUtils.buildPage(pageReqVO);
        // 转换返回
        Map<String, Object> params = new HashMap<>();
        if(StringUtils.isNotBlank(pageReqVO.getTitle())){
            params.put("title",pageReqVO.getTitle());
        }
        if(StringUtils.isNotBlank(pageReqVO.getCompanyName())){
            params.put("companyName",pageReqVO.getCompanyName());
        }
        if(StringUtils.isNotBlank(pageReqVO.getCreator())){
            params.put("creator",pageReqVO.getCreator());
        }
        if(StringUtils.isNotBlank(pageReqVO.getDept())){
            params.put("dept",pageReqVO.getDept());
        }
        if(StringUtils.isNotBlank(pageReqVO.getMobile())){
            params.put("mobile",pageReqVO.getMobile());
        }
        if(StringUtils.isNotBlank(pageReqVO.getEmail())){
            params.put("email",pageReqVO.getEmail());
        }
        if(null!=pageReqVO.getScheduleType()){
            params.put("scheduleType",pageReqVO.getScheduleType());
        }
        if(null!=pageReqVO.getStatus()){
            params.put("status",pageReqVO.getStatus());
        }
        if(null!=pageReqVO.getShowFlag()){
            params.put("showFlag",pageReqVO.getShowFlag());
        }
        if(StringUtils.isNotBlank(pageReqVO.getExamineFlag())){
            params.put("examineFlag",pageReqVO.getExamineFlag());
        }
        if(StringUtils.isNotBlank(pageReqVO.getExamineStatus())){
            params.put("examineStatus",pageReqVO.getExamineStatus());
        }
        if(null!=pageReqVO.getEntryStatus()){
            params.put("entryStatus",pageReqVO.getEntryStatus());
        }
        if(null!=pageReqVO.getProjectTypeId()){
            params.put("projectTypeId",pageReqVO.getProjectTypeId());
        }
        if(null!=pageReqVO.getDeleted()){
            params.put("deleted",pageReqVO.getDeleted());
        }else{
            params.put("deleted",0);
        }
        if(null!=pageReqVO.getStudentId()){
            params.put("studentId",pageReqVO.getStudentId());
        }
        params.put("queryType",pageReqVO.getQueryType());
        mpPage.setRecords(praxisProjectMapper.getPraxisProjectList(mpPage, params));
        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
    }
    @Override
    public void revertPraxisProject(Long id) {
        praxisProjectMapper.revertPraxisProject(id);
        this.saveProjectRecord(id,7);
    }
    @Override
    public List<PraxisProjectDO> getPraxisProjectList(PraxisProjectExportReqVO exportReqVO) {
        return praxisProjectMapper.selectList(exportReqVO);
    }

    @Override
    public List<PraxisAnnexVO> getPraxisAnnexListByProjectId(Long relationId, Integer relationType) {
        return praxisProjectMapper.getPraxisAnnexListByProjectId(relationId,relationType);
    }

    @Override
    public List<PraxisProjectScheduleVO> getScheduleListByProjectId(Long projectId) {
        return praxisProjectMapper.getScheduleListByProjectId(projectId);
    }

    @Override
    public PraxisProjectScheduleVO getNextScheduleByProjectId(Long projectId,Integer scheduleType) {
        return praxisProjectMapper.getNextScheduleByProjectId(projectId,scheduleType);
    }

    @Override
    public String validateScheduleTime(List<PraxisProjectScheduleVO> scheduleVOList ,int type){
        PraxisProjectScheduleVO scheduleVO_1 = scheduleVOList.stream().filter(m -> (1 == m.getScheduleType())).findFirst().orElse(null);
        PraxisProjectScheduleVO scheduleVO_4 = scheduleVOList.stream().filter(m -> (4 == m.getScheduleType())).findFirst().orElse(null);
        if(null==scheduleVO_1 || null== scheduleVO_1.getStartTime() || null== scheduleVO_1.getEndTime()){
            return "遴选时间不能为空";
        }
        if(null==scheduleVO_4 || null== scheduleVO_4.getStartTime() || null== scheduleVO_4.getEndTime() ){
            return "决赛时间不能为空";
        }
        if(type==1 && scheduleVO_1.getStartTime().before(new Date())){
            return "遴选开始时间必须大于当前时间";
        }
        if(scheduleVO_1.getStartTime().after(scheduleVO_1.getClosingDate()) ||scheduleVO_1.getEndTime().before(scheduleVO_1.getClosingDate())){
            return "遴选截止上传时间必须在开始时间和结束时间之间";
        }
        if(scheduleVO_4.getStartTime().after(scheduleVO_4.getClosingDate()) ||scheduleVO_4.getEndTime().before(scheduleVO_4.getClosingDate())){
            return "决赛截止上传时间必须在开始时间和结束时间之间";
        }
        if( scheduleVO_4.getStartTime().before(scheduleVO_1.getEndTime())){
            return "决赛开始时间必须大于遴选结束时间";
        }
        PraxisProjectScheduleVO scheduleVO_2 = scheduleVOList.stream().filter(m -> (2 == m.getScheduleType())).findFirst().orElse(null);
        if(null!=scheduleVO_2 ){
            if(scheduleVO_2.getStartTime().after(scheduleVO_2.getClosingDate()) ||scheduleVO_2.getEndTime().before(scheduleVO_2.getClosingDate())){
                return "初赛截止上传时间必须在开始时间和结束时间之间";
            }
            if( scheduleVO_2.getStartTime().before(scheduleVO_1.getEndTime())){
                return "初赛开始时间必须大于遴选结束时间";
            }
            if( scheduleVO_4.getStartTime().before(scheduleVO_2.getEndTime())){
                return "决赛开始时间必须大于初赛结束时间";
            }
        }
        PraxisProjectScheduleVO scheduleVO_3 = scheduleVOList.stream().filter(m -> (3 == m.getScheduleType())).findFirst().orElse(null);
        if(null!=scheduleVO_3 ){
            if(scheduleVO_3.getStartTime().after(scheduleVO_3.getClosingDate()) ||scheduleVO_3.getEndTime().before(scheduleVO_3.getClosingDate())){
                return "复赛截止上传时间必须在开始时间和结束时间之间";
            }
            if(null!=scheduleVO_2 && scheduleVO_3.getStartTime().before(scheduleVO_2.getEndTime())){
                return "复赛开始时间必须大于初赛结束时间";
            }
            if( scheduleVO_4.getStartTime().before(scheduleVO_3.getEndTime())){
                return "决赛开始时间必须大于复赛结束时间";
            }
        }
        return "";
    }

    @Override
    public String validateUpdateSchedule(List<PraxisProjectScheduleVO> scheduleVOList,Long projectId) {
        List<PraxisProjectScheduleVO> scheduleList= praxisProjectScheduleService.getScheduleListByProjectId(projectId);
        if(CollectionUtils.isNotEmpty(scheduleList)){
            PraxisProjectScheduleVO scheduleVO_1 = scheduleVOList.stream().filter(m -> (1 == m.getScheduleType())).findFirst().orElse(null);
            PraxisProjectScheduleVO schedule_1 = scheduleList.stream().filter(m -> (1 == m.getScheduleType())).findFirst().orElse(null);
            if(schedule_1.getStartTime().before(new Date()) &&
                            (scheduleVO_1.getStartTime().getTime()!= schedule_1.getStartTime().getTime()
                            ||scheduleVO_1.getEndTime().getTime()!= schedule_1.getEndTime().getTime()
                            ||scheduleVO_1.getClosingDate().getTime()!= schedule_1.getClosingDate().getTime()
                    )){
                return "遴选阶段已开始,不能修改";
            }
            PraxisProjectScheduleVO scheduleVO_2 = scheduleVOList.stream().filter(m -> (2 == m.getScheduleType())).findFirst().orElse(null);
            PraxisProjectScheduleVO schedule_2 = scheduleList.stream().filter(m -> (2 == m.getScheduleType())).findFirst().orElse(null);
            if(null!=scheduleVO_2 && null==schedule_2 && scheduleVO_2.getStartTime().before(new Date())){
                return "初赛阶段开始时间必须大于当前时间";
            }
            if(null!=scheduleVO_2 && null!=schedule_2 ){
                if(schedule_2.getStartTime().before(new Date()) &&
                        (scheduleVO_2.getStartTime().getTime()!= schedule_2.getStartTime().getTime()
                                ||scheduleVO_2.getEndTime().getTime()!= schedule_2.getEndTime().getTime()
                                ||scheduleVO_2.getClosingDate().getTime()!= schedule_2.getClosingDate().getTime()
                        )){
                    return "初赛阶段已开始,不能修改";
                }
            }
            PraxisProjectScheduleVO scheduleVO_3 = scheduleVOList.stream().filter(m -> (3 == m.getScheduleType())).findFirst().orElse(null);
            PraxisProjectScheduleVO schedule_3 = scheduleList.stream().filter(m -> (3 == m.getScheduleType())).findFirst().orElse(null);
            if(null!=scheduleVO_3 && null==schedule_3 && scheduleVO_3.getStartTime().before(new Date())){
                return "复赛阶段开始时间必须大于当前时间";
            }
            if(null!=scheduleVO_3 && null!=schedule_3 ){
                if(schedule_3.getStartTime().before(new Date()) &&
                        (scheduleVO_3.getStartTime().getTime()!= schedule_3.getStartTime().getTime()
                                ||scheduleVO_3.getEndTime().getTime()!= schedule_3.getEndTime().getTime()
                                ||scheduleVO_3.getClosingDate().getTime()!= schedule_3.getClosingDate().getTime()
                        )){
                    return "复赛阶段已开始,不能修改";
                }
            }

            PraxisProjectScheduleVO scheduleVO_4 = scheduleVOList.stream().filter(m -> (4 == m.getScheduleType())).findFirst().orElse(null);
            PraxisProjectScheduleVO schedule_4 = scheduleList.stream().filter(m -> (4 == m.getScheduleType())).findFirst().orElse(null);
            if(schedule_4.getStartTime().before(new Date()) &&
                    (scheduleVO_4.getStartTime().getTime()!= schedule_4.getStartTime().getTime()
                            ||scheduleVO_4.getEndTime().getTime()!= schedule_4.getEndTime().getTime()
                            ||scheduleVO_4.getClosingDate().getTime()!= schedule_4.getClosingDate().getTime()
                    )){
                return "决赛阶段已开始,不能修改";
            }
        }
        return "";
    }
    @Override
    public List<PraxisProjectRecordVO> getRecordByProjectId(Long id) {
        return praxisProjectMapper.getPraxisProjectRecordList(id);
    }

    @Override
    public PageResult<PraxisFeedBackVO> getFeedBackPageByProjectId(PraxisFeedBackPageReqVO pageVO) {
        // MyBatis Plus 查询
        SortingField sortingField = new SortingField();
        sortingField.setField("t.id");
        sortingField.setOrder("desc");
        pageVO.setSortField(sortingField);
        IPage<PraxisFeedBackVO> mpPage = MyBatisUtils.buildPage(pageVO);
        // 转换返回
        Map<String, Object> params = new HashMap<>();
        params.put("projectId",pageVO.getProjectId());
        params.put("feedbackStatus",1);
        mpPage.setRecords(praxisProjectMapper.getFeedBackPageByProjectId(mpPage, params));
        return new PageResult<>(mpPage.getRecords(), mpPage.getTotal());
    }

    @Override
    public Integer getProjectCountByTitle(String title, Long id) {
        return NumberUtils.getInteger(praxisProjectMapper.getProjectCountByTitle(title,id));
    }

    @Override
    @TenantIgnore
    @Async
    public void updateViewNum(Long id,Long userId) {
        praxisProjectMapper.updateViewNum(id);
        praxisProjectMapper.savePraxisViewDetail(id,userId,DateUtils.format(new Date(),"yyyy-MM"));
    }


    @Override
    public PraxisProjectCountVO getPraxisProjectCount(Long id) {
        PraxisProjectCountVO projectCount = praxisProjectMapper.getPraxisProjectCount(id);
        List<String> lastMonth12 = DateUtils.getLastMonth12();
        List<PraxisProjectViewCountVO> projectViewCount = praxisProjectMapper.getPraxisProjectViewCount(id, lastMonth12);
        if(CollectionUtils.isNotEmpty(projectViewCount)){
            List<PraxisProjectViewCountVO> newViewList=new ArrayList<>();
            for (String month:lastMonth12){
                PraxisProjectViewCountVO v = projectViewCount.stream().filter(m -> month.equals(m.getViewMonth())).findFirst().orElse(null);
                if(null==v){
                    PraxisProjectViewCountVO pv=new PraxisProjectViewCountVO();
                    pv.setNum(0L);
                    pv.setViewMonth(month);
                    newViewList.add(pv);
                }else{
                    newViewList.add(v);
                }
            }
            projectCount.setViewCountList(newViewList);
        }
        projectCount.setMajorList(praxisProjectMapper.getPraxisProjectMajorCount(id));
        projectCount.setBriskList(praxisProjectMapper.getPraxisProjectBriskCount());
        return projectCount;
    }
}
